/**
 * 
 * 
 *  
 *====================================================
 * 文件名称: StringUtils.java
 * 修订记录：
 * No    日期				作者(操作:具体内容)
 * 1.    Mar 3, 2009		(创建:创建文件)
 *       2004-11-16         陈雄华更改了splitString方法、增加了toVisualString方法、增加了subStringCount方法
 * 2.    Mar 3, 2009        根据 注释 规范进行调整
 *====================================================
 * 类描述： 
 * 
 */
package com.devframe.sys.util.common;

import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * <pre>
 * 字符串处理工具类.
 * &lt;blockquote&gt;
 * &lt;b&gt;数字格式化样式&lt;/b&gt;
 * &lt;table border=0 cellspacing=3 cellpadding=0 width=&quot;90%&quot;&gt;
 * <tr bgcolor="#ccccff">
 *      <th align=left>
 * Symbol
 * </th>
 *      <th align=left>
 * Location
 * </th>
 *      <th align=left>
 * Localized
 * </th>
 *      <th align=left>
 * Meaning
 * </th>
 *  </tr>
 *  <tr valign=top>
 *      <td><code>
 * 0</code></td>
 *      <td>
 * Number
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Digit
 * </td>
 *  </tr>
 *  <tr valign=top bgcolor="#eeeeff">
 *      <td><code>
 * #
 * </code></td>
 *      <td>
 * Number
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Digit, zero shows as absent
 * </td>
 *  </tr>
 *  <tr valign=top>
 *      <td><code>
 * .
 * </code></td>
 *      <td>
 * Number
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Decimal separator or monetary decimal separator
 * </td>
 *  </tr>
 *  <tr valign=top bgcolor="#eeeeff">
 *      <td><code>
 * -
 * </code></td>
 *      <td>
 * Number
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Minus sign
 * </td>
 *  </tr>
 *  <tr valign=top>
 *      <td><code>
 * ,
 * </code></td>
 *      <td>
 * Number
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Grouping separator
 * </td>
 *  </tr>
 *  <tr valign=top bgcolor="#eeeeff">
 *      <td><code>
 * E</code></td>
 *      <td>
 * Number
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Separates mantissa and exponent in scientific notation.
 * <em>
 * Need not be quoted in prefix or suffix.
 * </em></td>
 *  </tr>
 *  <tr valign=top>
 *      <td><code>
 * ;
 * </code></td>
 *      <td>
 * Subpattern boundary
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Separates positive and negative subpatterns
 * </td>
 *  </tr>
 *  <tr valign=top bgcolor="#eeeeff">
 *      <td><code>
 * %
 * </code></td>
 *      <td>
 * Prefix or suffix
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Multiply by 100 and show as percentage
 * </td>
 *  </tr>
 *  <tr valign=top>
 *      <td><code>
 *  \u2030
 * </code></td>
 *      <td>
 * Prefix or suffix
 * </td>
 *      <td>
 * Yes
 * </td>
 *      <td>
 * Multiply by 1000 and show as per mille
 * </td>
 *  </tr>
 *  <tr valign=top bgcolor="#eeeeff">
 *      <td><code>
 * ¤</code>
 *  (
 * <code>
 * \u00A4
 * </code>
 * )
 * </td>
 *      <td>
 * Prefix or suffix
 * </td>
 *      <td>
 * No
 * </td>
 *      <td>
 * Currency sign, replaced by currency symbol.  If
 *          doubled, replaced by international currency symbol.
 *          If present in a pattern, the monetary decimal separator
 *          is used instead of the decimal separator.
 * </td>
 *  </tr>
 *  <tr valign=top>
 *      <td><code>
 * '
 * </code></td>
 *      <td>
 * Prefix or suffix
 * </td>
 *      <td>
 * No
 * </td>
 *      <td>
 * Used to quote special characters in a prefix or suffix,
 *          for example,
 * <code>
 * &quot;'#'#&quot;
 * </code>
 *  formats 123 to
 * <code>
 * &quot;#123&quot;
 * </code>
 * .  To create a single quote
 *          itself, use two in a row:
 * <code>
 * &quot;# o''clock&quot;
 * </code>
 * .
 * </td>
 *   </tr>
 * &lt;/table&gt;
 * 
 * &lt;b&gt;符号(Symbol)通常是组合在一起使用的，例如下表&lt;/b&gt;
 * &lt;table border=0 cellspacing=3 cellpadding=0 width=&quot;90%&quot;&gt;
 * <tr bgcolor="#ccccff">
 *         <th align=left>
 * 输入
 * </th>
 *         <th align=left>
 * 格式
 * </th>
 *         <th align=left>
 * 输出
 * </th>
 *     </tr>
 *     <tr valign=top>
 *         <td rowspan=8>
 * 1234.123456
 * </td>
 *         <td><code>
 * 0</code></td>
 *         <td>
 * 1234
 * </td>
 *     </tr>
 *     <tr>
 *         <td><code>
 * 0.00
 * </code></td>
 *         <td>
 * 1234.12
 * </td>
 *     </tr>
 *     <tr>
 *         <td><code>
 * 0.###
 * </code></td>
 *         <td>
 * 1234.123
 * </td>
 *     </tr>
 *     <tr>
 *         <td><code>
 * 0.0000
 * </code></td>
 *         <td>
 * 1234.1235
 * </td>
 *     </tr>
 *     <tr>
 *         <td><code>
 * 00000000.00
 * </code></td>
 *         <td>
 * 00001234.12
 * </td>
 *     </tr>
 *     <tr>
 *         <td><code>
 * ,000.00
 * </code></td>
 *         <td>
 * 1,234.12
 * </td>
 *     </tr>
 *     <tr>
 *         <td><code>
 * ,00.00000000
 * </code></td>
 *         <td>
 * 12,34.12345600
 * </td>
 *     </tr>
 *     <tr>
 *         <td><code>
 * 0.00%
 * </code></td>
 *         <td>
 * 123412.35%
 * </td>
 *     </tr>
 *     <tr valign=top bgcolor="#eeeeff">
 *         <td rowspan=5>
 * 1234.100056
 * </td>
 *         <td><code>
 * 0</code></td>
 *         <td>
 * 1234
 * </td>
 *     </tr>
 *     <tr valign=top bgcolor="#eeeeff">
 *         <td><code>
 * 0.00
 * </code></td>
 *         <td>
 * 1234.10
 * </td>
 *     </tr>
 *     <tr valign=top bgcolor="#eeeeff">
 *         <td><code>
 * 0.##
 * </code></td>
 *         <td>
 * 1234.1
 * </td>
 *     </tr>
 *     <tr valign=top bgcolor="#eeeeff">
 *         <td><code>
 * (人民币),000.00
 * </code></td>
 *         <td>
 * (人民币)1,234.10
 * </td>
 *     </tr>
 *     <tr valign=top bgcolor="#eeeeff">
 *         <td><code>
 * ,000.########
 * </code></td>
 *         <td>
 * 1,234.100056
 * </td>
 *     </tr>
 * &lt;/table&gt;
 * <BR>
 * 注：0与#功能类似，区别在于用0表示位数时，格式化后的首尾的0会显示，而用#表示位数时，首尾的0不显示
 * &lt;/blockquote&gt;
 * </pre>
 * 
 * <BR>
 * <DL>
 * <DT><B>JDK版本:</B></DT>
 * <BR>
 * <DD>1.4</DD>
 * </DL>
 * 
 * @author 涂传滨，伊新煦，陈雄华，谢计生
 * @version 1.0
 * @since 1.0
 * @see java.text.DecimalFormat
 */
public final class StringUtils {

	/** 字符长度 */
	public static final int CHAR_LEN = 1;

	/** 字节长度 */
	public static final int BYTE_LEN = 2;

	private StringUtils() {
	}

	/**
	 * 数字字符串转化为整数
	 * 
	 * @param intStr
	 *            String 待转化的数字字符串
	 * @param intDef
	 *            int 当intStr为空或空字符串时返回的缺省值
	 * @return int 返回由数字字符串转化成的数字，当intStr为空或空字符串时，返回缺省值intDef
	 */
	public static int getInt(String intStr, int intDef) {
		if (null == intStr || "".equals(intStr.trim())) {
			return intDef;
		}

		int intRetu = intDef;

		Double db = new Double(intStr);
		intRetu = db.intValue();
		return intRetu;
	}

	/**
	 * 数字字符串转化为整数，在转化时发生异常，则返回0
	 * 
	 * @param intStr
	 *            String 待转化的数字字符串
	 * @return int 返回由数字字符串转化成的整数，当intStr为空或空字符串时，返回0
	 */
	public static int getInt(String intStr) {
		return getInt(intStr, 0);
	}

	/**
	 * 数字字符串转化为双精数字
	 * 
	 * @param dbstr
	 *            String 待转化的数字字符串
	 * @param dbDef
	 *            double 当dbstr为空或空字符串时返回的缺省值
	 * @return double 返回由数字字符串转化成的数字，当dbstr为空或空字符串时，则返回缺省值dbDef
	 */
	public static double getDouble(String dbstr, double dbDef) {

		if (null == dbstr || "".equals(dbstr.trim())) {
			return dbDef;
		}
		double dbRetu = dbDef;
		Double db = new Double(dbstr);
		dbRetu = db.doubleValue();
		return dbRetu;
	}

	/**
	 * 数字字符串转化为双精数字，在转化时发生异常，则返回0
	 * 
	 * @param dbstr
	 *            String 待转化的数字字符串
	 * @return double 返回由数字字符串转化成的数字，当dbstr为空或空字符串时，则返回0。
	 */
	public static double getDouble(String dbstr) {
		return getDouble(dbstr, 0);
	}

	/**
	 * 数字字符串转化为长整型
	 * 
	 * @param longstr
	 *            String 待转化的数字字符串
	 * @param longDef
	 *            long 当longstr为空或空字符串时返回的缺省值
	 * @return long 返回由数字字符串转化成的数字，当longstr为空或空字符串时，则返回缺省值longDef
	 */
	public static long getLong(String longstr, long longDef) {
		if (null == longstr || "".equals(longstr.trim())) {
			return longDef;
		}
		long longRetu = longDef;

		Double db = new Double(longstr);
		longRetu = db.longValue();

		return longRetu;
	}

	/**
	 * 数字字符串转化为长整型，在转化时发生异常，则返回0
	 * 
	 * @param longstr
	 *            String 待转化的数字字符串
	 * @return long 返回由数字字符串转化成的数字，当longstr为空或空字符串时，则返回0。
	 */
	public static long getLong(String longstr) {
		return getLong(longstr, 0);
	}

	/**
	 * 字符串转化为布尔型
	 * 
	 * @param booleanstr
	 *            String 待转化的字符串
	 * @param booleanDef
	 *            boolean 当字符串为空或为null时返回的值
	 * @return boolean 返回转化化的布尔值，只有当booleanstr为字符串“true”(忽略大小写)时才返回true， <BR>
	 *         如果在转化时发生异常（只有为null时），则返回缺省值booleanDef
	 */
	public static boolean getBoolean(String booleanstr, boolean booleanDef) {
		if (null == booleanstr) {
			return booleanDef;
		}
		boolean booleanRetu = booleanDef;
		if ("true".equalsIgnoreCase(booleanstr.trim())) {
			booleanRetu = true;
		}

		return booleanRetu;
	}

	/**
	 * 字符串转化为布尔型. <BR>
	 * 只有当booleanstr为字符串“true”(忽略大小写)时才返回true，其它都返回false, 包括booleanstr为null
	 * 
	 * @param booleanstr
	 *            String 待转化的字符串
	 * @return boolean 返回转化化的布尔值，
	 */
	public static boolean getBoolean(String booleanstr) {
		return getBoolean(booleanstr, false);
	}

	/**
	 * 双精数字格式化，返回字符串
	 * 
	 * @param db
	 *            double 待格式化的双精数字
	 * @param fmt
	 *            String 格式化样式，参见类说明， <BR>
	 *            fmt非法时，db将按原样转化为字符串后返回。
	 * @return String 格式化后的数字，以字符串方式返回
	 */
	public static String getNumFormat(double db, String fmt) {
		String retu = "";
		if (null == fmt || "".equals(fmt.trim())) {
			return Double.toString(db);
		}

		try {
			DecimalFormat decimalformat = new DecimalFormat(fmt);
			retu = decimalformat.format(db);
			decimalformat = null;
		} catch (IllegalArgumentException iaex) {
			// iaex.printStackTrace();
			retu = Double.toString(db);
		}
		return retu;
	}

	/**
	 * 双精数字格式化，把入参中的双精数格式化为带两位小数的数字字符串
	 * 
	 * @param db
	 *            double 待格式化的双精数字
	 * @return String 格式化为两位小数的数字字符串
	 */
	public static String getNumFormat(double db) {
		return getNumFormat(db, "0.00");
	}

	/**
	 * 数字字符串格式化，返回字符串
	 * 
	 * @param numStr
	 *            String 待格式化的数字字符串， <BR>
	 *            如果numStr参数不是的数字则不进行格式化，按原样返回
	 * @param fmt
	 *            String 格式化样式，参见类说明 <BR>
	 *            fmt非法时，将把numStr按原样返回。
	 * @return String 格式化后的字符串
	 */
	public static String getNumFormat(String numStr, String fmt) {
		double db = getDouble(numStr, 0);
		return getNumFormat(db, fmt);
	}

	/**
	 * 数字字符串格式化，把入参中的数字字符串格式化为带两位小数的数字字符串
	 * 
	 * @param numStr
	 *            String 待格式化的数字字符串， <BR>
	 *            如果numStr参数不是的数字则不进行格式化，按原样返回
	 * @return String 格式化为两位小数的数字字符串
	 */
	public static String getNumFormat(String numStr) {
		return getNumFormat(numStr, "0.00");
	}

	/**
	 * 普通字符串转化为网页中可显示的，如回车转化为&lt;br&gt;.
	 * 
	 * @param str
	 *            String 待转化的字符串
	 * @return String 转化后的字符串
	 */
	public static String htmlEncode(String str) {
		String retu = null;
		if (null == str || "".equals(str.trim())) {
			retu = str;
		} else {
			String html = str;
			//StringUtils tool = new StringUtils();
			html = replaceString(html, "&", "&amp;");
			html = replaceString(html, "<", "&lt;");
			html = replaceString(html, ">", "&gt;");
			html = replaceString(html, "\r\n", "\n");
			html = replaceString(html, "\n", "<br>");
			html = replaceString(html, "\t", "    ");
			html = replaceString(html, " ", "&nbsp;");
			html = replaceString(html, "\"", "&quot;");
			retu = html;
			html = null;
		}
		return retu;
	}

	/**
	 * 字符串替换，把str字符串中的所有oldStr子串替换为newStr字串
	 * 
	 * @param sourceStr
	 *            String 将被替换的字符串，为null时不执行任何替换操作
	 * @param oldStr
	 *            String 将被替换的子串，为null或为空字符串时不执行替换操作
	 * @param newStr
	 *            String 将被替换成的子串，为null时不执行替换操作
	 * @param isIgnoreCase
	 *            boolean 是否忽略大小写，true表忽略大小写，false表大小写敏感。
	 * @return String 替换后的字符串
	 */
	public static String replaceString(String sourceStr, String oldStr, String newStr, boolean isIgnoreCase) {
		if (sourceStr == null || oldStr == null || oldStr.equals("")) {
			return null;
		}
		String strRetStr = sourceStr;
		int pos = strRetStr.indexOf(oldStr);
		while (pos != -1) {
			strRetStr = strRetStr.substring(0, pos) + newStr + strRetStr.substring(pos + oldStr.length());
			pos = strRetStr.indexOf(oldStr, pos + newStr.length());
		}
		return strRetStr;
	}

	/**
	 * 字符串替换，把str字符串中的所有oldStr子串替换为newStr字串(大小写敏感)
	 * 
	 * @param sourceStr
	 *            String 将被替换的字符串，为null时不执行任何替换操作
	 * @param oldStr
	 *            String 将被替换的子串，为null或为空字符串时不执行替换操作
	 * @param newStr
	 *            String 将被替换成的子串，为null时不执行替换操作
	 * @return String 替换后的字符串
	 */
	public static String replaceString(String sourceStr, String oldStr, String newStr) {
		return replaceString(sourceStr, oldStr, newStr, false);
	}

	/**
	 * 字符串按指定分隔符分解为一个数组（大小写敏感）. <BR>
	 * 例子： <BR>
	 * String[] array = StringUtils.splictString("AA/BBB/CCC//DDDD//" , "/" );
	 * <BR>
	 * 结果： <BR>
	 * array[0]="AA" array[1]="BBB" array[2]="CCC" array[3]="DDDD"
	 * 
	 * @param sourceStr
	 *            String 源字符串
	 * @param splitStr
	 *            String 分隔符
	 * @param isTrim
	 *            boolean
	 * @return String[] 字符串数组, <BR>
	 *         源字符串为null或为空字符串时，返回长度为1的数组，元素值为空字符串 <BR>
	 *         分隔符为null或为空字符串时，返回长度为1的数组，元素值为源字符串
	 */
	public static String[] splitString(String sourceStr, String splitStr, boolean isTrim) {
		String newSourceStr = sourceStr;
		String newSplitStr = splitStr;

		if (newSourceStr == null || newSplitStr == null) {
			return null;
		}

		if (isTrim) // 去掉开始和结束的分隔符
		{
			// 开头的间隔符去掉
			while (newSourceStr.indexOf(newSplitStr) == 0) {
				newSourceStr = newSourceStr.substring(newSplitStr.length());
			}

			// 尾部的间隔符去掉
			while (newSourceStr.indexOf(newSplitStr, newSourceStr.length() - newSplitStr.length()) > -1) {
				newSourceStr = newSourceStr.substring(0, sourceStr.length() - newSplitStr.length());
			}
		}
		if (newSourceStr.equals("") || newSplitStr.equals("")) {
			return null;
		}
		return splitString(newSourceStr, newSplitStr);
	}

	/**
	 * 功能简述 :把字符串放入一个数组
	 * 
	 * @param sourceStr
	 *            要被放入的字符串
	 * @param splitStr
	 *            间隔符
	 * @return 转换后的数组,sourceStr或splitStr ＝ null 或 "" 返回null
	 */
	public static String[] splitString(String sourceStr, String splitStr) {
		String newSourceStr = sourceStr;
		String newSplitStr = splitStr;

		if (newSourceStr == null || newSplitStr == null) {
			return null;
		}
		if (newSourceStr.equals("") || newSplitStr.equals("")) {
			return null;
		}
		int intArraySize = subStringCount(newSourceStr, newSplitStr);
		// 如果为-1则返回
		if (intArraySize == -1) {
			return null;
		}

		newSourceStr += newSplitStr;

		String[] strRetArr = new String[intArraySize + 1];
		int intpos = newSourceStr.indexOf(newSplitStr);
		int intArrayPos = 0;
		while (intpos != -1) {
			strRetArr[intArrayPos++] = newSourceStr.substring(0, intpos);
			newSourceStr = newSourceStr.substring(intpos + newSplitStr.length());
			intpos = newSourceStr.indexOf(newSplitStr);
		}

		return strRetArr;
	}

	/**
	 * 功能简述 :把字符串放入一个数组
	 * 
	 * @param sourceStr
	 *            要被放入的字符串
	 * @param splitStr
	 *            间隔符
	 * @return 转换后的List,sourceStr或splitStr ＝ null 或 "" 返回元素个数为0的List
	 */
	public static List splitString2List(String sourceStr, String splitStr) {
		String[] tempArr = splitString(sourceStr, splitStr);
		List resultList = new ArrayList();
		if (tempArr != null) {
			for (int i = 0; i < tempArr.length; i++) {
				resultList.add(tempArr[i]);
			}
		}
		return resultList;
	}

	/**
	 * 功能简述 :把字符串放入一个数组
	 * 
	 * @param sourceStr
	 *            要被放入的字符串
	 * @param splitStr
	 *            间隔符
	 * @param isTrim
	 *            boolean
	 * @return 转换后的List,sourceStr或splitStr ＝ null 或 "" 返回元素个数为0的List
	 */
	public static List splitString2List(String sourceStr, String splitStr, boolean isTrim) {
		String[] tempArr = splitString(sourceStr, splitStr, isTrim);
		List resultList = new ArrayList();
		if (tempArr != null) {
			for (int i = 0; i < tempArr.length; i++) {
				resultList.add(tempArr[i]);
			}
		}
		return resultList;
	}

	/**
	 * 功能简述 :在一个字符串中查找字符串个数(不区分大小写)
	 * 
	 * @param sourceStr
	 *            要被查询的字符串
	 * @param subStr
	 *            要查找的字符串
	 * @return 找到的个数
	 */
	public static int subStringCount(String sourceStr, String subStr) {
		// 如果是空指针则返回-1
		if (sourceStr == null || subStr == null) {
			return -1;
		}
		if (sourceStr.equals("") || subStr.equals("")) {
			return -1;
		}
		int result = 0;
		int intPos = sourceStr.toUpperCase().indexOf(subStr.toUpperCase());
		while (intPos != -1) {
			result++;
			intPos = sourceStr.toUpperCase().indexOf(subStr.toUpperCase(), intPos + subStr.length());
		}

		return result;
	}

	/**
	 * 用指定的分隔符把字符串数组合并成一个字符串. 数组为null或长度为0时返回空字符串 <BR>
	 * 例子： <BR>
	 * String[] array = {"1",null,"","3"}; <BR>
	 * StringUtils.arrayToString(array,"|"); <BR>
	 * 返回结果：1|||3
	 * 
	 * @param array
	 *            String[] 待合并的数组
	 * @param splitStr
	 *            String 数组各元素合并后，它们之间的分隔符，为null时用空字符串代替
	 * @return String 合并后的字符串
	 */
	public static String arrayToString(String[] array, String splitStr) {
		if (null == array || 0 == array.length) {
			return "";
		}
		String newSplitStr = splitStr;
		if (null == newSplitStr) {
			newSplitStr = "";
		}
		StringBuffer strBuf = new StringBuffer("");
		int len = array.length;
		for (int i = 0; i < len - 1; i++) {
			strBuf.append((null == array[i]) ? "" : array[i]).append(newSplitStr);
		}
		strBuf.append((null == array[len - 1]) ? "" : array[len - 1]);

		return strBuf.toString();
	}

	/**
	 * 用默认分隔符 | 把字符串数组合并成一个字符串. 数组为null或长度为0时返回空字符串
	 * 
	 * @param array
	 *            String[] 待合并的数组
	 * @return String 合并后的字符串
	 */
	public static String arrayToString(String[] array) {
		return arrayToString(array, "|");
	}

	/**
	 * 判断字符串是否为null或为空字符串（包括只含空格的字符串）
	 * 
	 * @param str
	 *            String 待检查的字符串
	 * @return boolean 如果为null或空字符串（包括只含空格的字符串）则返回true，否则返回false
	 */
	public static boolean isNullBlank(String str) {
		return (null == str || "".equals(str.trim())) ? true : false;
	}

	/**
	 * 从字符串中得到指定位置的子串（按分隔符分隔，大小写敏感）. <BR>
	 * 例子： <BR>
	 * StringUtils.decomposeString("a||b|c|d","|",1); <BR>
	 * StringUtils.decomposeString("a||b|c|d","|",2); <BR>
	 * StringUtils.decomposeString("a||b|c|d","|",3); <BR>
	 * StringUtils.decomposeString("a||b|c|d","|",4); <BR>
	 * StringUtils.decomposeString("a||b|c|d","|",5); <BR>
	 * 返回结果： <BR>
	 * a,空字符串,b,c,d
	 * 
	 * @param sourceStr
	 *            String 源字符串
	 * @param splitStr
	 *            String 分隔符
	 * @param pos
	 *            int 位置，从1开始
	 * @return String 返回指定位置的子串。 <BR>
	 *         当分隔符为null或为空字符串时返回源字符串； <BR>
	 *         当源字符串为null或为空字符串时返回空字符串； <BR>
	 *         当指定位置小于1或大于分隔符个数-1时返回空字符串。
	 */
	public static String decomposeString(String sourceStr, String splitStr, int pos) {
		String retu = "";
		String newSourceStr = sourceStr;
		if (null == newSourceStr || "".equals(newSourceStr.trim())) {
			return "";
		}

		if (pos <= 0) {
			return "";
		}

		if (null == splitStr || "".equals(splitStr)) {
			return sourceStr;
		}

		newSourceStr = newSourceStr + splitStr;
		String tmpStr = newSourceStr;

		int splitLen = splitStr.length();
		int tmpLen = tmpStr.length();

		for (int i = 0; i < pos - 1; i++) {
			int tmpPosi = tmpStr.indexOf(splitStr);
			if (tmpPosi < 0 || tmpPosi + splitLen >= tmpLen) {
				tmpStr = splitStr;
				break;
			} else {
				tmpStr = tmpStr.substring(tmpPosi + splitLen);
			}
		}
		retu = tmpStr.substring(0, tmpStr.indexOf(splitStr));
		return retu;
	}

	/**
	 * 从字符串中得到指定位置的子串（按分隔符 | 分隔）.
	 * 
	 * @param sourceStr
	 *            String 源字符串
	 * @param pos
	 *            int 位置，从1开始
	 * @return String 返回指定位置的子串。 <BR>
	 *         当分隔符为null或为空字符串时返回源字符串； <BR>
	 *         当源字符串为null或为空字符串时返回空字符串； <BR>
	 *         当指定位置小于1或大于分隔符个数-1时返回空字符串。
	 */
	public static String decomposeString(String sourceStr, int pos) {
		return decomposeString(sourceStr, "|", pos);
	}

	/**
	 * 删除指定的前导、后导子串（大小写敏感）. <br>
	 * 例子： <br>
	 * StringUtils.trim("and and username = '123' and password = 'abc' and
	 * ","and "); <br>
	 * 结果：username = '123' and password = 'abc'
	 * 
	 * @param sourceStr
	 *            String 待删除的字符串
	 * @param removeChar
	 *            char 子串
	 * @return String 处理后的字符串
	 */
	public static String trim(String sourceStr, char removeChar) {
		if (sourceStr == null) {
			return null;
		}
		String newSourceStr = sourceStr;

		newSourceStr = newSourceStr.trim();
		int loIntBegin = 0;
		int loIntEnd = 0;
		int loIntLen = newSourceStr.length();
		for (int i = 0; i < loIntLen; i++) {
			if (newSourceStr.charAt(i) == removeChar) {
				loIntBegin++;
			} else {
				break;
			}
		}
		for (int i = 0; i < loIntLen; i++) {
			if (newSourceStr.charAt(loIntLen - 1 - i) == removeChar) {
				loIntEnd++;
			} else {
				break;
			}
		}
		return newSourceStr.substring(loIntBegin, loIntLen - loIntEnd);
	}

	/**
	 * 删除指定的前导、后导子串（大小写敏感）. <br>
	 * 例子： <br>
	 * StringUtils.trim("and and username = '123' and password = 'abc' and
	 * ","and "); <br>
	 * 结果：username = '123' and password = 'abc'
	 * 
	 * @param sourceStr
	 *            String 待删除的字符串
	 * @param removeChar
	 *            char 子串
	 * @param end
	 *            true 只trim末尾，false 只trim头部
	 * @return String 处理后的字符串
	 */
	public static String trim(String sourceStr, char removeChar, boolean end) {
		if (sourceStr == null) {
			return null;
		}
		String newSourceStr = sourceStr;

		newSourceStr = newSourceStr.trim();
		int loIntBegin = 0;
		int loIntEnd = 0;
		int loIntLen = newSourceStr.length();
		for (int i = 0; i < loIntLen; i++) {
			if (newSourceStr.charAt(i) == removeChar) {
				loIntBegin++;
			} else {
				break;
			}
		}
		for (int i = 0; i < loIntLen; i++) {
			if (newSourceStr.charAt(loIntLen - 1 - i) == removeChar) {
				loIntEnd++;
			} else {
				break;
			}
		}
		if (end) {
			return newSourceStr.substring(0, loIntLen - loIntEnd);
		} else {
			return newSourceStr.substring(loIntBegin);
		}
	}

	/**
	 * <pre>
	 * 将字符串截短到特定的长度,一个中文是两个字节的长度，但是是1个字符的长度，例：
	 * 1)truncate(&quot;公司&quot;,2,CHAR_LEN) = &quot;巨龙&quot;
	 * 2)truncate(&quot;公司&quot;,2,BYTE_LEN) = &quot;巨&quot;
	 * 3)truncate(&quot;test&quot;,2,CHAR_LEN) = &quot;dr&quot;
	 * 4)truncate(&quot;test&quot;,2,BYTE_LEN) = &quot;dr&quot;
	 * </pre>
	 * 
	 * @param str
	 *            String 需要截的字符串
	 * @param len
	 *            int 截到的目标长度
	 * @param lenType
	 *            int 长度类型,字符长度{@link CHAR_LEN},字符长度{@link BYTE_LEN}
	 * @return String
	 */
	public static String truncate(String str, int len, int lenType) {
		if (str == null) {
			return str;
		}
		// 字符长度
		if (lenType == CHAR_LEN) {
			if (str.length() <= len) {
				return str;
			} else {
				return str.substring(0, len);
			}
		} else // 字节长度
		{
			StringBuffer sb = new StringBuffer();
			int temp = 0;

			for (int i = 0; i < str.length(); i++) {
				if (i < len) // 是否到指定的长度
				{
					temp = ("" + str.charAt(i)).getBytes().length;
					if (i + temp <= len) {
						sb.append(str.charAt(i));
					} else {
						break;
					}
				} else {
					break;
				}
			}
			return sb.toString();
		}
	}

	/**
	 * 从源字符串中从第一个字符开始取出给定长度的字串. <BR>
	 * 源字符串长度大于len时，尾巴追加一个appendStr串
	 * 
	 * @param sourceStr
	 *            String 源字符串
	 * @param len
	 *            int 取出的长度
	 * @param appendStr
	 *            String 追加的字符串（常用的appendStr为...）
	 * @return String 取出的子串
	 */
	public static String substring(String sourceStr, int len, String appendStr) {
		if (null == sourceStr || "".equals(sourceStr)) {
			return sourceStr;
		}
		if (len <= 0) {
			return "";
		}

		String newappendStr = appendStr;
		if (null == newappendStr) {
			newappendStr = "";
		}

		int sourceLen = sourceStr.length();
		if (len >= sourceLen) {
			return sourceStr;
		} else {
			return sourceStr.substring(0, len) + newappendStr;
		}
	}

	/**
	 * 产生指定长度随机字符串（包括字母及数字）.
	 * 
	 * @param length
	 *            int 随机字符串长度
	 * @return String 随机字符串
	 */
	public static String random(int length) {
		String retu = "";
		int d1;
		int d2;
		char[] letters = initLetters();
		//int[] numbers = initNumbers();

		for (int i = 0; i < length; i++) {
			// d1 = ((int) (Math.random() * 10) % 2);
			d1 = (int) (Math.random() * 10) % 2;

			if (d1 == 0) { // use a letter
				// d2 = ((int) (Math.random() * 100) % 52);
				d2 = (int) (Math.random() * 100) % 52;
				retu += letters[d2];
			} else if (d1 == 1) { // use a number
				retu += (int) (Math.random() * 10);
			}
		}
		return retu;
	}

	/**
	 * 产生纯字母的随机字符串
	 * 
	 * @param length
	 *            int 随机字符串长度
	 * @return String 随机字符串
	 */
	public static String randomString(int length) {
		String retu = "";
		int d2;
		char[] letters = initLetters();

		for (int i = 0; i < length; i++) {
			// d2 = ((int) (Math.random() * 100) % 52);
			d2 = (int) (Math.random() * 100) % 52;
			retu += letters[d2];
		}
		return retu;
	}

	/**
	 * 产生纯数字随机字符串
	 * 
	 * @param length
	 *            int 随机字符串长度
	 * @return String 随机字符串
	 */
	public static String randomNumber(int length) {
		String retu = "";
		//int[] numbers = initNumbers();

		for (int i = 0; i < length; i++) {
			retu += (int) (Math.random() * 10);
		}
		return retu;
	}

	/**
	 * 内部方法，产生字母数组
	 * 
	 * @return char[]
	 */
	private static char[] initLetters() {
		char[] ca = new char[52];
		for (int i = 0; i < 26; i++) {
			ca[i] = (char) (65 + i);
		}
		for (int i = 26; i < 52; i++) {
			ca[i] = (char) (71 + i);
		}
		return ca;
	}

	/**
	 * 内部方法，产生数字数组
	 * 
	 * @return int[]
	 */
	/*private static int[] initNumbers() {
		int[] na = new int[10];
		for (int i = 0; i < 10; i++) {
			na[i] = i;
		}
		return na;
	}*/

	/**
	 * 对字符串进行加减密处理.
	 * 
	 * @param source
	 *            String 待加减密处理的字符串
	 * @param flag
	 *            boolean true表进行加密，false表进行减密
	 * @return String 处理后的字符串. <BR>
	 *         source为空则返回原字符串source， <BR>
	 *         如果source中含有中文字符则对这一中文字符不处理.
	 */
	public static String encrypt(String source, boolean flag) {
		if (null == source || "".equals(source.trim())) {
			return source;
		}
		String lsKEY1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz~!@#$%^&*(),.;[]{}";
		String lsKEY2 = "&*()AD;[BFLCGH]{PQ}EI!JKRYZ1MSTXNO23UV,.Wcd45ef6lm7g@h0a#$nij8ob%^ptvz9ku~qrswxy";

		char[] chSource = source.toCharArray();

		StringBuffer strBuf = new StringBuffer(chSource.length);

		int pos;
		int len = chSource.length;
		for (int i = 0; i < len; i++) {
			if (flag) { // 加密
				pos = lsKEY1.indexOf(chSource[i]);
				if (pos >= 0) {
					strBuf.append(lsKEY2.substring(pos, pos + 1));
				} else {
					strBuf.append(chSource[i]);
				}
			} else { // 减密
				pos = lsKEY2.indexOf(chSource[i]);
				if (pos >= 0) {
					strBuf.append(lsKEY1.substring(pos, pos + 1));
				} else {
					strBuf.append(chSource[i]);
				}
			}
		}

		return strBuf.toString();

	}

	/**
	 * 将null字符串转换为空串，方便HTML的显示
	 * 
	 * @param sourceStr
	 *            待处理的字符串
	 * @return String 处理的的字符串
	 */
	public static String toVisualString(String sourceStr) {
		if (sourceStr == null || sourceStr.equals("")) {
			return "";
		} else {
			return sourceStr;
		}
	}

	/**
	 * 将字段填充到指定的长度
	 * 
	 * @param sourceStr
	 *            String 操作字符串
	 * @param length
	 *            int 指定长度
	 * @param withChar
	 *            char 填充的字符
	 * @param isPadToEnd
	 *            boolean 是否填充在字符的尾部 true ：是 ,false:填充在头部
	 * @return String
	 */
	public static String pad(String sourceStr, int length, char withChar, boolean isPadToEnd) {
		if (sourceStr == null) {
			return null;
		}
		if (sourceStr.length() >= length) {
			return sourceStr;
		}

		StringBuffer sb = new StringBuffer(sourceStr);
		for (int i = 0; i < length - sourceStr.length(); i++) {
			if (isPadToEnd) {
				sb.append(withChar);
			} else {
				sb.insert(0, withChar);
			}
		}
		return sb.toString();

	}

	/**
	 * main
	 * 
	 * @param args
	 *            String[]
	 * @author:Administrator
	 */
	public static void main(String[] args) {
		// String aa = ",,,aa,aa,aa,,,,";
		// System.out.println("array:"+splitString(aa,",").length);
		// System.out.println("array:"+splitString(aa,",",true).length);
		System.out.println(truncate("a%a%asdf", 2, BYTE_LEN));
		System.out.println(truncate("a$a$asd", 4, CHAR_LEN));
		System.out.println(truncate("ddd", 6, BYTE_LEN));
		System.out.println(truncate("sses", 6, CHAR_LEN));
	}

	/**
	 * 将身份证号码转换为18位
	 * 
	 * @param xIdCode
	 *            String
	 * @return String
	 */
	public static String idTo18(String xIdCode) {
		int idLength = xIdCode.length();
		String newIdCode = "";
		switch (idLength) {
		case 15:
			String serial = xIdCode.substring(idLength - 3);
			if (serial.equals("996") || serial.equals("997") || serial.equals("998") || serial.equals("999")) {
				newIdCode = xIdCode.substring(0, 6) + "18" + xIdCode.substring(idLength - 9);
			} else {
				newIdCode = xIdCode.substring(0, 6) + "19" + xIdCode.substring(idLength - 9);
			}
			newIdCode = newIdCode + getIdCheckBit(newIdCode);
			break;
		case 17:
			newIdCode = xIdCode + getIdCheckBit(xIdCode);
			break;
		case 18:
			newIdCode = xIdCode;
			break;
		default:
			newIdCode = xIdCode;
		}
		return newIdCode;
	}

	/**
	 * 将身份证号转换为15位
	 * 
	 * @param xIdCode
	 *            String
	 * @return String
	 */
	public static String idTo15(String xIdCode) {
		String result = xIdCode;
		String temp = "";
		if (xIdCode.length() == 18) {
			temp = temp + xIdCode.substring(0, 6) + xIdCode.substring(8, 17);
			result = temp;
		}
		return result;
	}

	/**
	 * getIdCheckBit
	 * 
	 * @param xId
	 *            id
	 * @return String
	 * @author:Administrator
	 */
	private static String getIdCheckBit(String xId) {
		String[] strCheckChar = new String[11];
		int[] nWeight = new int[18];
		strCheckChar[0] = "1";
		strCheckChar[1] = "0";
		strCheckChar[2] = "X";
		strCheckChar[3] = "9";
		strCheckChar[4] = "8";
		strCheckChar[5] = "7";
		strCheckChar[6] = "6";
		strCheckChar[7] = "5";
		strCheckChar[8] = "4";
		strCheckChar[9] = "3";
		strCheckChar[10] = "2";
		nWeight[0] = 7;
		nWeight[1] = 9;
		nWeight[2] = 10;
		nWeight[3] = 5;
		nWeight[4] = 8;
		nWeight[5] = 4;
		nWeight[6] = 2;
		nWeight[7] = 1;
		nWeight[8] = 6;
		nWeight[9] = 3;
		nWeight[10] = 7;
		nWeight[11] = 9;
		nWeight[12] = 10;
		nWeight[13] = 5;
		nWeight[14] = 8;
		nWeight[15] = 4;
		nWeight[16] = 2;
		nWeight[17] = 1;
		int sumMult = 0;
		for (int i = 0; i <= 16; i++) {
			String ch = xId.substring(i, i + 1);
			sumMult = sumMult + (Integer.parseInt(ch) * nWeight[i]);
		}
		int resultMod = sumMult % 11;
		return strCheckChar[resultMod];
	}

	/**
	 * MD5加密算法
	 * 
	 * @更新时间:Apr 22, 2008
	 * @更新作者:Ryan Wong
	 * @param s
	 *            String
	 * @return String
	 */
	public static String md5(String s) {
		char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		try {
			byte[] strTemp = s.getBytes();
			MessageDigest mdTemp = MessageDigest.getInstance("MD5");
			mdTemp.update(strTemp);
			byte[] md = mdTemp.digest();
			int j = md.length;
			char[] str = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 取得字符串中间的几位
	 * 
	 * @更新时间:Apr 22, 2008
	 * @更新作者:Ryan Wong
	 * @param strsource
	 *            str_source
	 * @param midlength
	 *            midlength
	 * @return String
	 */
	public static String getMidString(String strsource, int midlength) {
		String strMid = "";
		int length = strsource.length();
		if (midlength > length) {
			return null;
		}
		if (length % 2 == 0) {
			if (midlength % 2 != 0) {
				return null;
			}
			strMid = strsource.substring(length / 2 - midlength / 2, length / 2 + midlength / 2);

		} else {
			if (midlength % 2 == 0) {
				return null;
			}
			strMid = strsource.substring((length - 1) / 2 - (midlength - 1) / 2, (length - 1) / 2
					+ (midlength - 1) / 2 + 1);

		}
		return strMid;
	}

	public static boolean isNotBlank(String value){
	    return (value!=null) && !value.equals("");
	}
	
    public static boolean isBlank(String value){
        return (value==null) || value.equals("");
    }
    /**
     * getStringToInt
     * @param value String
     * @param defaultInt int
     * @return int
     * @author:Administrator
     */
    public static int getStringToInt(String value, int defaultInt) {
        int i = defaultInt;
        if (isNotBlank(value) ) {
            Integer intObject = getStringByInt(value);
            if(intObject!=null){
                return intObject.intValue();
            }
        }
        return i;
    }

    /**
     * 字符串替换
     * @param value String
     * @param replaceChar String
     * @return String
     * @author:Administrator
     */
    public static String replaceStr(String value, String replaceChar) {
        String returnValue = "";
        if (isNotBlank(value)) {
            returnValue = value.replaceAll("[" + replaceChar + "]", "");
        }
        return returnValue;
    }

    /**
     * getNullByString
     * @param value String
     * @return String
     * @author:Administrator
     */
    public static String getNullByString(String value) {
        String values = "";
        if (isNotBlank(value)) {
            values = value.trim();
        }
        return values;
    }

    /**
     * getNullByString 
     * @param value String
     * @param defaultValue String
     * @return String
     * @author:Administrator
     */
    public static String getNullByString(String value, String defaultValue) {
        String values = "";
        if (isNotBlank(value)) {
            values = value;
        } else {
            values = defaultValue;
        }
        return values;
    }

    /**
     * getStringByInt
     * @param value String
     * @return Integer
     * @author:Administrator
     */
    public static Integer getStringByInt(String value) {
        Integer intValue = null;
        if (isNotBlank(value) ) {
            try{
                intValue = Integer.valueOf(value);
            } catch(NumberFormatException ex){
                
            }
        }
        return intValue;
    }

    /**
     * getStringByMaxLen 
     * @param value String
     * @param maxLen  int
     * @return String
     * @author:Administrator
     */
    public static String getStringByMaxLen(String value, int maxLen) {
        String returnValue = "";
        if (isNotBlank(value)) {
            returnValue = value.length() > maxLen ? value.substring(0, maxLen) : value;
        }
        return returnValue;
    }

    /**
     * getCheckBoxValueByStr
     * @param value String
     * @return String
     * @author:Administrator
     */
    public static String getCheckBoxValueByStr(String value) {
        String returnValue = "";
        if (isNotBlank(value)) {
            if (value.equals("on")) {
                returnValue = "1";
            } else {
                returnValue = "0";
            }
        }
        return returnValue;
    }	
}
